package server

import (
	"bytes"
	"context"
	"encoding/json"
	core "gitee.com/dreamwood/ez"
	"net/http"
)

type Operation struct {

	//链路key
	ChainKey string

	//处理数据输入
	Input *Input
	//处理数据输出
	Output *Output
	//作为协作模式的数据共享中心
	//Coordination Coordination
	Handler *EzHandler
	//操作计时器
	Timer *core.Timer
	//Logger
	Logger *core.Logger

	//是否中止
	IsStop bool
}

func NewOperation(resp http.ResponseWriter, req *http.Request) *Operation {
	op := new(Operation)
	op.ChainKey = core.CreateRandString(64)
	//初始化输入数据
	in := GetInputFromRequest(req)
	op.Input = in
	//初始化输出数据
	out := new(Output)
	out.Response = resp
	bf := bytes.NewBuffer([]byte{})
	out.Writer = bf
	op.Output = out
	//初始化操作计时器
	op.Timer = core.NewTimer()
	//加载默认Logger
	EzLogger := core.CreateLogger()
	EzLogger.InitConsoleLogger()
	EzLogger.UseConsoleLogger()
	op.Logger = EzLogger

	op.IsStop = false

	return op
}

func (this *Operation) Get(key string) *InputAnyThing {
	return this.Input.Get(key)
}

func (this *Operation) GetHeader() http.Header {
	return this.Input.Request.Header
}

func (this *Operation) SetHeader(key string, value string) {
	this.Input.Request.Header.Set(key, value)
}

func (this *Operation) CreateContext() context.Context {
	return context.WithValue(context.Background(), "operation", this)
}

func (this *Operation) FillJson(model interface{}) error {
	return json.Unmarshal(this.Input.Json, model)
}

func (this *Operation) JsonOut(data interface{}) {
	this.Output.Json(data)
}
func (this *Operation) Html(data string) {
	this.Output.Html(data)
}

func (this *Operation) Stop() {
	this.IsStop = true
}

// Handler
func (this *Operation) StopHandle() {
	this.Handler.IsStop = true
}
func (this *Operation) SetPublic(dataName string, data interface{}) {
	this.Handler.Set(dataName, data)
}
func (this *Operation) GetPublic(dataName string) interface{} {
	return this.Handler.Get(dataName)
}

func GetOperationFromContext(ctx context.Context) *Operation {
	v := ctx.Value("operation")
	find, ok := v.(*Operation)
	if ok {
		return find
	} else {
		return nil
	}
}
